上回說了希望選擇學習火屬性魔法後,艾草帶我走到一棵大樹下。
艾草:「來嘗試用自己現有的魔力試試看能否選取到樹上紅色的果實。」
「呃啊啊啊...呼哈呼哈...魔力呀,聽我號令,供我使喚...(下略一百字」
艾草:「就算把所有中二台詞都說完了,也不會選比較快唷!別急,等選到了來教你怎麼改體內的元素。」
「我我好像感覺到了,體內一股熱氣,從胃部到喉嚨,這難道就是魔力的感覺嗎?」
艾草:「那是你的胃食道逆流啦(・⊝・) ,沒關係,我從頭教導你選取方法吧!」
DOM 的英文全名是:Document Object Model ,那它指的是什麼呢?
平常我們在寫 HTML 的時候只會看到一堆程式碼,但網頁是如何解析我們撰寫的這些程式碼呢?
其實是透過 DOM tree 節點樹狀圖的方式,如下:

DOM tree 是從 document 物件的根節點開始透過樹狀結構的方式,一路解析下來,而我們在操作網頁元素時,可以去選取每個節點,並設定想要的操作,來達成想要的網頁互動效果。
也因為瀏覽器解析 HTML 結構是由上往下解析的關係,所以當你把要載入的 JavaScript 檔案放置於 head 時,卻想操作 body 內的節點時,會無法操作!
因為當瀏覽器一解析到  JavaScript 檔案,會跑去執行 JavaScript 檔案,執行完成後就不再執行了,所以要記得擺放於 body 上方!
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <!-- JavaScript 檔案載入放置處 -->
  <script src="all.js"></script>
</body>
</html>
選取節點的方式有很多種,這邊來介紹我最常使用到的 querySelector 方式!
我們可以使用 querySelector 的方式選取想要的 Element ,而它會回傳符合的第一個節點,querySelector 的選取方式是透過字串的形式,且是使用 CSS 選擇器的方式選取。
HTML:
<h1 id="title" class="title"></h1>
JavaScript:
console.log(document.querySelector('h1'))//<h1 id="title" class="title"></h1>
console.log(document.querySelector('.title'))//<h1 id="title" class="title"></h1>
console.log(document.querySelector('#title')//<h1 id="title" class="title"></h1>
既然說了是透過 CSS 選擇器的方式選取,當然以上三種方法都選的到 h1 Element ,如果想透過後代選擇器方式選取也可以:
HTML:
<ul>
  <li></li>
</ul>
JavaScript:
console.log(document.querySelector('ul li'))//<li></li>
剛剛有提到 querySelector 是選取到第一個節點,那如果我們 Element 想一次選取多個可以怎麼做呢?
可以透過 querySelectorAll 的方式。
querySelectorAll 可以選取多個 Element ,並透過 nodeList 的方式回傳給我們,如下:
HTML:
<a href="#">連結一</a>
<a href="#">連結二</a>
<a href="#">連結三</a>
JavaScript:
console.log(document.querySelectorAll('a'))//["<a/>","<a/>","<a/>"]
而該  nodeList 為類陣列物件,為何說是類陣列呢?
因為如果要讀取其中的資料,是必須透過陣列方式去讀取的。
HTML:
<a href="#">連結一</a>
<a href="#">連結二</a>
<a href="#">連結三</a>
JavaScript:
console.log(document.querySelectorAll('a')[0])//<a href="#">連結一</a>
另外 nodeList 也可以使用陣列方法 forEach 唷!
當我們選取到想要的 Element 後想在裡面插入文字內容可以使用什麼方式呢?
textContent 可以讓你在想要的節點 Node 插入文字 Text,請特別注意插入文字的地方指的是:
如果我想將某個 h1 Element 內的 Text 從"標題"改成"我是新標題",可以這樣寫:
HTML:
<h1>標題</h1>
JavaScript:
//透過 querySelector 選取 h1 Element 
let el = document.querySelector("h1");
//使用 textContent 替換文字內容
el.textContent = "我是新標題";
更改後的結果,就會顯示我是新標題囉!
但要留意,使用這個方法會將原有的文字內容覆蓋掉。
既然剛剛特別提到 textContent 是插入文字 Text ,那一定也有插入元素 Element 的方法,那就是 innerHTML !
可以透過 innerHTML 來插入 element 元素。
例如想在列表元素 ul 內插入 li ,可以這樣操作:
HTML:
<ul class="list">
  <li>我是原本就存在的 li </li>
</ul>
JavaScript:
//透過 querySelector 選取 class list 
let list = document.querySelector(".list");
//使用 innerHTML 插入 Element
list.innerHTML = "<li>我是新增的 li </li>";
顯示後的結果:
因為 innerHTML 會將原有的內容覆蓋掉,所以會只剩下"我是新增的 li"。
可以透過 getAttribute 來讀取網頁元素的屬性,什麼是屬性呢?
如 a 連結的 href 、 img 的 src 等,每個不同的 HTML 元素內都會有對應的屬性,而我們可以使用 getAttribute 讀取那些屬性。
屬性舉例:

讀取的方式如下:
HTML:
<a href="#"></a>
JavaScript:
console.log(document.querySelector('a').getAttribute("href"))//#
透過 getAttribute() 這個函式,並將屬性用字串的方式當成參數填進去,就能成功讀取出屬性囉。
我們可以透過 setAttribute() 這個函式來新增或更改屬性的值,它總共需要傳入兩個參數,分別為:
而需要透過字串形式的方式,兩個參數間使用, 逗號區隔。
使用方式如下:
HTML:
<a href="#"></a>
JavaScript:
//透過 querySelector 選取 a
const link = document.querySelector("a");
// 透過 setAttribute 更改 href 屬性的值為 "https://www.google.com.tw/"
link.setAttribute("href","https://www.google.com.tw/")
console.log(link)//<a href="https://www.google.com.tw/"></a>
body 內querySelector 可以選取第一個符合的 Element
querySelectorAll 可以選取多個符合的 Element ,並透過 nodeList 回傳textContent 可以插入文字 Text 內容innerHTML 可以插入 element 元素getAttribute() 可以讀取網頁元素的屬性setAttribute() 可以更改網頁元素的屬性值,可以傳入兩個參數:
請問以下敘述何者錯誤?
A 網頁解析 HTML 時會透過 DOM tree 節點樹狀圖的方式
B querySelector、querySelectorAll 都可以選取 element 元素,差別在 querySelector 僅能選取第一個符合的
C 如果想讀取元素屬性,可以透過 getAttribute() 、想修改元素屬性,可以透過 setAttribute()
D 透過 innerHTML 插入element 元素時,不會覆蓋原本的element 元素,會透過新增的方式插入element 元素
解答: D 錯誤,使用 innerHTML 或 textContent 皆會覆蓋掉原本的內容
JavaScript 必修篇 - 前端修練全攻略(六角學院)